/**
 * Monorepo构建脚本
 * 用于按照依赖顺序构建所有包
 */

const { execSync } = require('child_process');
const path = require('path');
const fs = require('fs');

/**
 * 执行命令并打印输出
 * @param {string} command - 要执行的命令
 * @param {string} cwd - 工作目录
 */
function exec(command, cwd) {
  console.log(`在 ${cwd} 中执行: ${command}`);
  try {
    execSync(command, { cwd, stdio: 'inherit' });
  } catch (error) {
    console.error(`执行命令失败: ${error.message}`);
    process.exit(1);
  }
}

/**
 * 获取工作区中的所有包
 * @returns {Array<{name: string, path: string, dependencies: string[]}>}
 */
function getWorkspacePackages() {
  const rootDir = path.resolve(__dirname, '..');
  const packagesDir = path.join(rootDir, 'packages');
  const appsDir = path.join(rootDir, 'apps');
  
  const packages = [];
  
  // 读取packages目录下的所有包
  if (fs.existsSync(packagesDir)) {
    fs.readdirSync(packagesDir).forEach(pkgName => {
      const pkgPath = path.join(packagesDir, pkgName);
      const pkgJsonPath = path.join(pkgPath, 'package.json');
      
      if (fs.existsSync(pkgJsonPath)) {
        const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
        packages.push({
          name: pkgJson.name,
          path: pkgPath,
          dependencies: getDependencies(pkgJson)
        });
      }
    });
  }
  
  // 读取apps目录下的所有应用
  if (fs.existsSync(appsDir)) {
    fs.readdirSync(appsDir).forEach(appName => {
      const appPath = path.join(appsDir, appName);
      const appJsonPath = path.join(appPath, 'package.json');
      
      if (fs.existsSync(appJsonPath)) {
        const appJson = JSON.parse(fs.readFileSync(appJsonPath, 'utf-8'));
        packages.push({
          name: appJson.name,
          path: appPath,
          dependencies: getDependencies(appJson)
        });
      }
    });
  }
  
  return packages;
}

/**
 * 从package.json中提取工作区依赖
 * @param {object} pkgJson - package.json内容
 * @returns {string[]} - 工作区依赖列表
 */
function getDependencies(pkgJson) {
  const deps = [];
  const allDeps = {
    ...pkgJson.dependencies,
    ...pkgJson.devDependencies
  };
  
  for (const [name, version] of Object.entries(allDeps)) {
    if (version.includes('workspace:')) {
      deps.push(name);
    }
  }
  
  return deps;
}

/**
 * 按照依赖顺序构建所有包
 */
function buildPackages() {
  const packages = getWorkspacePackages();
  const built = new Set();
  
  function buildPackage(pkg) {
    if (built.has(pkg.name)) return;
    
    // 先构建依赖
    for (const depName of pkg.dependencies) {
      const depPkg = packages.find(p => p.name === depName);
      if (depPkg) {
        buildPackage(depPkg);
      }
    }
    
    console.log(`\n构建包: ${pkg.name}`);
    exec('pnpm build', pkg.path);
    built.add(pkg.name);
  }
  
  // 构建所有包
  for (const pkg of packages) {
    buildPackage(pkg);
  }
}

// 执行构建
console.log('开始按依赖顺序构建所有包...');
buildPackages();
console.log('\n所有包构建完成!');